package com.audaque.springboot.foshanupload.web.reactivedemo.reactor;

import java.io.IOException;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.util.Iterator;
import java.util.Set;

/**
 * @author zgb
 * @desc 反应器
 * @date 2023-08-08 21:47:01
 */

public class Reactor implements Runnable {
    //每条线程负责一个选择器的查询
    final Selector selector;

    public Reactor(Selector selector) {
        this.selector = selector;
    }

    public void run() {
        try {
            while (!Thread.interrupted()) {
                //单位为毫秒
                //每隔一秒列出选择器感应列表
                selector.select(1000);
                Set<SelectionKey> selectedKeys = selector.selectedKeys();
                if (null == selectedKeys || selectedKeys.size() == 0) {
                    //如果列表中的通道注册事件没有发生那就继续执行
                    continue;
                }
                Iterator<SelectionKey> it = selectedKeys.iterator();
                while (it.hasNext()) {
                    //Reactor负责dispatch收到的事件
                    SelectionKey sk = it.next();
                    dispatch(sk);
                }
                //清楚掉已经处理过的感应事件，防止重复处理
                selectedKeys.clear();
            }
        } catch (IOException ex) {
            ex.printStackTrace();
        }
    }


    void dispatch(SelectionKey sk) {
        Runnable handler = (Runnable) sk.attachment();
        //调用之前attach绑定到选择键的handler处理器对象
        if (handler != null) {
            handler.run();
        }
    }
}

